<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <div style="height: 2000px"></div>
    <img
      src=""
      data-src="https://img-blog.csdnimg.cn/20210617233951118.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MjY1MDU5,size_16,color_FFFFFF,t_70#pic_center"
      alt=""
    />
  </body>
  <script>
    function Person2(name) {
      this.name = name;
    }
    let a = new Person2("2");
    console.log(a);
    // js
    // node
    // 浏览器
    // vue3
    // koa
    // bind call apply
    // promise
    // aync await
    // 浏览器运行机制，node运行机制
    // 浏览器缓存策略

    function Person() {
      this.name = 1;
    }
    let xdj = new Person();
    console.log(Object.prototype.toString.call([1, 2])); //[object Array]
    console.log([1, 2].toString()); //1,2
    console.log(Object.prototype.toString.call(xdj)); //1,2

    //bind
    var obj = {
      name: "若川",
    };
    function original(a, b) {
      console.log(this.name);
      console.log([a, b]);
      return false;
    }
    var bound = original.bind(obj, 1);
    var boundResult = bound(2); // '若川', [1, 2]
    console.log(boundResult); // false
    console.log(original.bind.name); // 'bind'
    console.log(original.bind.length); // 1
    console.log(original.bind().length); // 2 返回original函数的形参个数
    console.log(bound.name); // 'bound original'
    console.log(function () {}.bind().name); // 'bound '
    console.log(function () {}.bind().length); // 0
    //bind实现第一版(基于apply实现)
    Function.prototype.bindFn = function bind(thisArg) {
      if (typeof this !== "function") {
        throw new TypeError(this + "must be a function");
      }
      // 存储函数本身
      var self = this;
      // 去除thisArg的其他参数 转成数组
      var args = [].slice.call(arguments, 1);
      var bound = function () {
        // bind返回的函数 的参数转成数组
        var boundArgs = [].slice.call(arguments);
        // apply修改this指向，把两个函数的参数合并传给self函数，并执行self函数，返回执行结果
        return self.apply(thisArg, args.concat(boundArgs));
      };
      return bound;
    };
    // 测试
    var obj = {
      name: "若川",
    };
    function original(a, b) {
      console.log(this.name);
      console.log([a, b]);
    }
    var bound = original.bindFn(obj, 1);
    bound(2); // '若川', [1, 2]

    var obj1 = {
      name: "若川",
    };
    function original1(a, b) {
      console.log("this", this); // original1 {}
      console.log("typeof this", typeof this); // object
      this.name = b;
      console.log("name", this.name); // 2
      console.log("this", this); // original1 {name: 2}
      console.log([a, b]); // 1, 2
    }
    var bound1 = original1.bind(obj1, 1);
    var newBoundResult = new bound1(2);
    // console.log(newBoundResult, 'newBoundResult'); // original {name: 2}

    function Person(uName) {
      if (new.target !== undefined) {
        this.userName = uName;
      } else {
        throw new Error("必须用new实例化");
      }
    }

    let testObj = {
      name: "xdj",
    };
    function test() {
      this.name = "show";
    }
    test.bind(testObj);
    console.log(testObj);

    //apply
    Function.prototype.apply_new = function (thisObj) {
      //调用的不是函数抛出异常
      if (typeof this !== "function") {
        throw new TypeError(`${this} is not function`);
      }
      //第一个参数的this指向不传在非严格模式下为window
      if (thisObj === null || typeof thisObj === "undefined") {
        thisObj = window;
      }
      let args = arguments[1];
      let result;
      thisObj.fn = this;
      if (typeof args !== "object") {
        throw new TypeError(`参数不是数组`);
      }
      if (args) {
        result = thisObj.fn(...args);
      } else {
        result = thisObj.fn();
      }
      return result;
    };
    async function test() {
      return "1";
    }
    console.log(test());
    // test().then(res => console.log(res))
    var date = new Date();
    console.log(121);
    console.log(121);
    console.log(121);
    console.log(121);
    console.log(121);
    console.log(121);
    let x = 4;
    if (x > 2) {
      console.log(2);
    }
    setTimeout(() => {
      var currentDate = new Date();
      console.log(currentDate - date);
    }, 1000);

    console.log("script start");
    async function async1() {
      await async2();
      console.log("async1 end");
    }
    async function async2() {
      console.log("async2 end");
    }
    async1();

    setTimeout(function () {
      console.log("setTimeout");
    }, 0);

    new Promise((resolve) => {
      console.log("Promise");
      resolve();
    })
      .then(function () {
        console.log("promise1");
      })
      .then(function () {
        console.log("promise2");
      });

    console.log("script end");
    // script start => async2 end => Promise => script end => async1 end => promise1 => promise2  => setTimeout
    console.log(1);

    setTimeout(() => {
      console.log(2);
      new Promise((resolve) => {
        console.log(4);
        resolve();
      }).then(() => {
        console.log(5);
      });
    });

    new Promise((resolve) => {
      console.log(7);
      resolve();
    }).then(() => {
      console.log(8);
    });

    setTimeout(() => {
      console.log(9);
      new Promise((resolve) => {
        console.log(11);
        resolve();
      }).then(() => {
        console.log(12);
      });
    });
  </script>
  <script>
    var images = document.getElementsByTagName("img");
    const observer = new IntersectionObserver(callback);
    for (let i of images) {
      observer.observe(i);
    }
    function callback(entries) {
      for (let i of entries) {
        console.log(i);
        if (i.isIntersecting) {
          let img = i.target;
          let trueSrc = img.getAttribute("data-src");
          img.setAttribute("src", trueSrc);
          observer.unobserve(img);
        }
      }
    }
    // window.addEventListener("scroll", (e) => {
    //   changeImgSrc()
    // });
    // function changeImgSrc(){
    //   for (let i of images) {
    //     if (i.offsetTop <= window.innerHeight + window.scrollY) {
    //       //获取自定义data-src属性的值
    //       let trueSrc = i.getAttribute("data-src");
    //       //把值赋值给图片的src属性
    //       i.setAttribute("src", trueSrc);
    //     }
    //   }
    // }
  </script>
</html>
